#!/usr/bin/python
# -*- coding:utf-8 -*-
# @time: 2021/7/7 3:05 下午

import re

from rest_framework import serializers

TYPE_CHOICES = (
    ('work', 'work'),
    ('mgmt', 'mgmt'),
    ('mirror', 'mirror'),
)

TAG_CHOICES = (("dns", "dns"), ("network", "network"))

IPv4_FORMAT = '^(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))$'
IPv6_FORMAT = '^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$'


def is_ipv4(address):
    ret = re.match(IPv4_FORMAT, address)
    if ret:
        return True
    return False


def is_ipv6(address):
    ret = re.match(IPv6_FORMAT, address)
    if ret:
        return True
    return False


class NetworkSerializer(serializers.Serializer):
    name = serializers.CharField(required=False)
    type = serializers.ChoiceField(required=False, choices=TYPE_CHOICES)
    tag = serializers.ChoiceField(choices=TAG_CHOICES)
    ipv4_addr = serializers.CharField(
        required=False, allow_null=True, error_messages={'blank': 'IPv4地址不能为空'}
    )
    ipv4_netmask = serializers.CharField(
        required=False, allow_null=True, error_messages={'blank': 'IPv4掩码不能为空'}
    )
    ipv4_gateway = serializers.CharField(
        required=False, allow_null=True, error_messages={'blank': 'IPv4网关不能为空'}
    )
    ipv6_addr = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    ipv6_netmask = serializers.CharField(
        required=False, allow_null=True, allow_blank=True
    )
    ipv6_gateway = serializers.CharField(
        required=False, allow_null=True, allow_blank=True
    )
    primary_dns = serializers.CharField(
        required=False, allow_null=True, allow_blank=True
    )
    secondary_dns = serializers.CharField(
        required=False, allow_null=True, allow_blank=True
    )

    def validate_ipv4_addr(self, value):
        if value and not is_ipv4(value):
            raise serializers.ValidationError('IPv4地址不是一个有效IP')
        return value

    def validate_ipv4_netmask(self, value):
        if value and not is_ipv4(value):
            raise serializers.ValidationError('IPv4掩码不是一个有效IP')
        return value

    def validate_ipv4_gateway(self, value):
        if value and not is_ipv4(value):
            raise serializers.ValidationError('IPv4网关不是一个有效IP')
        return value

    def validate_ipv6_addr(self, value):
        if value and not is_ipv6(value):
            raise serializers.ValidationError('IPv6地址不是一个有效IP')
        return value

    def validate_ipv6_netmask(self, value):
        if value and not is_ipv6(value):
            raise serializers.ValidationError('IPv6前缀不是一个有效IP')
        return value

    def validate_ipv6_gateway(self, value):
        if value and not is_ipv6(value):
            raise serializers.ValidationError('IPv6网关不是一个有效IP')
        return value

    def validate_primary_dns(self, value):
        if value and not is_ipv4(value):
            raise serializers.ValidationError('DNS不是一个有效IP')
        return value

    def validate_secondary_dns(self, value):
        if value and not is_ipv4(value):
            raise serializers.ValidationError('备用DNS不是一个有效IP')
        return value

    def validate(self, attrs):
        tag = attrs.get("tag")
        primary_dns = attrs.get("primary_dns")
        secondary_dns = attrs.get("secondary_dns")
        name = attrs.get("name")
        _type = attrs.get("type")
        ipv4_addr = attrs.get("ipv4_addr")
        ipv4_netmask = attrs.get("ipv4_netmask")
        ipv4_gateway = attrs.get("ipv4_gateway")
        if tag == "dns" and not primary_dns:
            raise serializers.ValidationError("请输入有效的IPv4 dns地址")
        if tag == "network" and not all(
            [name, _type, ipv4_addr, ipv4_netmask, ipv4_gateway]
        ):
            raise serializers.ValidationError("修改网口配置， 缺少参数")
        if not secondary_dns:
            attrs.pop("secondary_dns", "")
        return attrs


class RouteSerializer(serializers.Serializer):
    name = serializers.CharField(required=True)
    type = serializers.ChoiceField(required=True, choices=TYPE_CHOICES)
    to = serializers.CharField(required=True, error_messages={'blank': '目标IP不能为空'})
    via = serializers.CharField(required=True, error_messages={'blank': '网关IP不能为空'})
    netmask = serializers.CharField(required=True, error_messages={'blank': '子网掩码不能为空'})

    def validate_to(self, value):
        if value and not (is_ipv4(value) or is_ipv6(value)):
            raise serializers.ValidationError('目标IP不是一个有效IP')
        return value

    def validate_via(self, value):
        if value and not (is_ipv4(value) or is_ipv6(value)):
            raise serializers.ValidationError('网关IP不是一个有效IP')
        return value

    def validate_netmask(self, value):
        if value and not (is_ipv4(value) or is_ipv6(value)):
            raise serializers.ValidationError('子网掩码不是一个有效IP')
        return value
